Repository navigation
fix(jwt): let x-litellm-team-id select DB membership teams when the token also carries a team claim - #43206
Conversation
…oken also carries a team claim Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".
|
|
|
|
@greptileai please review |
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
Sync on means the IdP is the source of truth, so DB memberships equal the JWT teams by design. Documented as scope in the Caveats section |
|
Updated the fallback_to_db_teams description in b15d3d6 to cover header selection when the token carries team claims |
|
@greptileai please re-review b15d3d6 |
* feat(model-catalog): add Rust registry validation (#43136) * doc * feat(model-catalog): add Rust registry validation * test(model-catalog): ignore integration tests * docs(model-catalog): fix validation note grammar --------- Co-authored-by: Yujong Lee <yujong@berri.ai> (cherry picked from commit c289d5d) * test(rust): reorganize core crate tests and split cache and OCR suites (#43177) * test(rust): group cache tests under cache/ and fold test_ocr.py into ocr/ The two failure cases in test_ocr.py duplicated the upstream-500 and timeout rows of PUBLIC_FAILURES, so only the file-input encoding case moves to ocr/test_requests.py Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(rust): split the response cache suite into one file per backend test_response_cache.py grew to 2400 lines. Each backend now has its own file, shared fixtures live in cache/conftest.py and shared helpers in support/cache.py. The helpers alias the private native test handles once, dropping the per-call reportPrivateUsage hits Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * split tokenizer test * test(core): consolidate route integration tests under tests/ with rstest and wiremock Moves the public-API OCR route tests out of src/ocr/route.rs and document.rs into tests/ocr/, split per provider plus lifecycle, machine, and document tests, merging the duplicated pairs. Messages, audio transcription, and chat completions share one wiremock-based upstream and recording secret source in tests/support, and gain table-driven cases for auth, routing, upstream errors, streaming, and declines. Tests of litellm-llms items move to that crate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(messages): keep the stream relay test independent of the stream head contents The stream head carries no headers on main, so the relay test asserts the open-then-deliver order and the relayed body instead of header hand-off. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: Yujong Lee <yujong@berri.ai> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 1041379) * feat(rust): hand upstream response headers to the native Messages stream (#43178) * ci: drop the ocr_testing job now that tests/ocr_tests is gone Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(ocr): restore the live OCR matrix and the ocr_testing job The public litellm.ocr / aocr / Router interface is unchanged by the Rust migration, so the live provider matrix still applies. Drops the stale VCR skip list for the deleted test_rust_bridge.py. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(messages): show streamed upstream headers never reach the native stream The Python handler puts the upstream response headers on the stream's _hidden_params before the first chunk so the proxy can forward them as llm_provider-* headers. The native route drops them, and this test fails on the Rust path while passing on Python. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * feat(messages): hand upstream response headers to the native stream before its first chunk The Messages route fills MessagesStreamHead from the upstream response and yields it on Open. The Python driver converts it through the protocol host and hands it to Stream and SyncStream as their _hidden_params, so a streamed native call carries additional_headers the same way the Python handler does and the proxy can forward them as llm_provider-* headers. The relay contract lives in the core crate test, the hand-off in the host-python driver test, and the header projection in the route host test, so the recording-server test that showed the gap is dropped. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * wip --------- Co-authored-by: Yujong Lee <yujong@berri.ai> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 081f73f) * feat(testkit): agent clients for Claude Code, Codex and opencode (#43181) * feat(testkit): install and configure Claude Code, Codex and opencode against a gateway Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * refactor(testkit): derive targets from target-lexicon and split agents behind a trait Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * refactor(testkit): group sources into agent and install folders Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * feat(testkit): split agents into install, configure and drive with semver-aware launch Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * style(testkit): drop a needless borrow Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: Yujong Lee <yujong@berri.ai> Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> (cherry picked from commit 9c10e0f) * ci: run migrated unit selections on every event in legacy GHA shards (#43182) * ci: run the unit_selection.sh shard files on every event instead of only fork pull requests Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * ci: rename fork-flag to unit-flag now that it applies on every event --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> (cherry picked from commit 694783e) * test: move tests/test_litellm root and small trees into tests/unit (#43186) * ci: run the unit_selection.sh shard files on every event instead of only fork pull requests Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * ci: rename fork-flag to unit-flag now that it applies on every event * test: move tests/test_litellm root and small trees into tests/unit Pure renames, no content changes. Follow-up commits in this PR fix references, merge the three files that already existed in tests/unit, keep live-provider tests in tests/test_litellm and wire CI. * test: carry tests/test_litellm conftest isolation into tests/unit Callback lists, routing fallbacks, cached HTTP clients, logger state, AWS, proxy-URL and keychain env, and session-end client cleanup now reset for unit tests too. The environment isolation owns its MonkeyPatch so a test's own monkeypatch is undone before the model-cost teardown runs. * test: merge, split and prune the moved root and small-tree tests Merge batches/test_batch_utils.py and the chat_completions and messages dispatch tests into the files that already existed in tests/unit. Keep the live Gemini interactions tests, the async image-fetch format test and the OpenAI embedding scorer test in tests/test_litellm since they need real network or keys. Put test_router.py under tests/unit/test_router so the existing package no longer shadows it. Delete eight tests the audit found superseded by stronger ones kept in this move. * ci: run the moved root and small-tree tests under their legacy flags Add the misc and responses-caching-types flags to unit_selection.sh and CircleCI, extend enterprise-routing and mcp-integration, and point the legacy GHA shards, Makefile, redis-compat workflow, merge smoke manifest and change classifier at the new paths. * test: make the new tests/unit directories packages tests/unit/test_package_layout.py requires every directory to carry an __init__.py, and without one the moved and retained test_litellm_responses_bridge.py modules collide on import. * test: scope the unit socket block to tests/unit in shared sessions The GHA shards collect the legacy test-path and the unit selection in one pytest session. The unit conftest's loopback-only block leaked into legacy modules that reach the network at import. The legacy conftest now lifts the restriction at collect and setup time, and the unit conftest re-applies it when collecting its own modules. * test: give the shard-script tests their own GITHUB_OUTPUT They only passed where the runner set it. The CircleCI unit job's env allowlist drops it, so the script's redirect failed there. * test: point the router and module-deletion checks at tests/unit router_code_coverage and code_qa_check_tests only searched tests/test_litellm, so the moved router tests no longer counted. The two silent-experiment tests the audit deleted were the only direct callers of those methods; they are replaced with tests that assert the forwarded shadow request and the recursion guard. --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> (cherry picked from commit f688224) * refactor(framer): replace Framer trait with tokio-util codecs (#43193) * refactor(framer): replace Framer trait with tokio-util codecs Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * refactor(framer): port SSE and AWS event stream framing to codecs Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(rust): drop clone on Copy capabilities in messages request test Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(rust): use field init shorthand in messages request test Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: Yujong Lee <yujong@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> (cherry picked from commit 3c93ea1) * test: move tests/test_litellm/llms into tests/unit/llms (#43191) * ci: run the unit_selection.sh shard files on every event instead of only fork pull requests Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * ci: rename fork-flag to unit-flag now that it applies on every event * test: move tests/test_litellm root and small trees into tests/unit Pure renames, no content changes. Follow-up commits in this PR fix references, merge the three files that already existed in tests/unit, keep live-provider tests in tests/test_litellm and wire CI. * test: carry tests/test_litellm conftest isolation into tests/unit Callback lists, routing fallbacks, cached HTTP clients, logger state, AWS, proxy-URL and keychain env, and session-end client cleanup now reset for unit tests too. The environment isolation owns its MonkeyPatch so a test's own monkeypatch is undone before the model-cost teardown runs. * test: merge, split and prune the moved root and small-tree tests Merge batches/test_batch_utils.py and the chat_completions and messages dispatch tests into the files that already existed in tests/unit. Keep the live Gemini interactions tests, the async image-fetch format test and the OpenAI embedding scorer test in tests/test_litellm since they need real network or keys. Put test_router.py under tests/unit/test_router so the existing package no longer shadows it. Delete eight tests the audit found superseded by stronger ones kept in this move. * ci: run the moved root and small-tree tests under their legacy flags Add the misc and responses-caching-types flags to unit_selection.sh and CircleCI, extend enterprise-routing and mcp-integration, and point the legacy GHA shards, Makefile, redis-compat workflow, merge smoke manifest and change classifier at the new paths. * test: make the new tests/unit directories packages tests/unit/test_package_layout.py requires every directory to carry an __init__.py, and without one the moved and retained test_litellm_responses_bridge.py modules collide on import. * test: scope the unit socket block to tests/unit in shared sessions The GHA shards collect the legacy test-path and the unit selection in one pytest session. The unit conftest's loopback-only block leaked into legacy modules that reach the network at import. The legacy conftest now lifts the restriction at collect and setup time, and the unit conftest re-applies it when collecting its own modules. * test: move tests/test_litellm/llms into tests/unit/llms Rename-only. Moves the provider tests and the fine-tuning fixtures they load, mirroring the old paths. Follow-up commits merge, split and wire them. * test: merge, split and prune the moved llms tests Merges the Databricks chat transformation tests into the existing unit file, keeps the tests that need real keys or the network in tests/test_litellm, deletes the audited tests a stronger unit test already covers, and points imports at tests.unit.llms. * ci: run the moved llms tests under their legacy flags The Vertex AI and All Other Providers shards keep their legacy test-path for the retained files and add the llm-vertex-ai and llm-other-providers unit selections. CircleCI gets matching unit jobs. * test: make the tests/unit/llms directories packages Adds __init__.py to the moved dirs and drops the legacy ones whose directories no longer hold tests. * test: drop script runners and path hacks the llms split left dangling The __main__ runners in the split openai_like files and the Databricks e2e runner called tests that now live in the other half of the split or were deleted. The retained legacy halves also no longer need sys.path edits. * test: give the shard-script tests their own GITHUB_OUTPUT They only passed where the runner set it. The CircleCI unit job's env allowlist drops it, so the script's redirect failed there. * test: point the router and module-deletion checks at tests/unit router_code_coverage and code_qa_check_tests only searched tests/test_litellm, so the moved router tests no longer counted. The two silent-experiment tests the audit deleted were the only direct callers of those methods; they are replaced with tests that assert the forwarded shadow request and the recursion guard. * test: keep the Databricks manual e2e runner and fix the SageMaker Nova run path The Databricks e2e file is a manual script whose main() calls the tests that were pruned, so pruning them broke the documented run. It is back to its main version. The SageMaker Nova docstring now points at the file's real location in tests/local_testing. * test: keep the job's UNIT_FLAG out of the shard-script tests --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> (cherry picked from commit 5e6dc89) * test: move tests/test_litellm integrations and secret_managers into tests/unit (#43194) * ci: run the unit_selection.sh shard files on every event instead of only fork pull requests Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * ci: rename fork-flag to unit-flag now that it applies on every event * test: move tests/test_litellm root and small trees into tests/unit Pure renames, no content changes. Follow-up commits in this PR fix references, merge the three files that already existed in tests/unit, keep live-provider tests in tests/test_litellm and wire CI. * test: carry tests/test_litellm conftest isolation into tests/unit Callback lists, routing fallbacks, cached HTTP clients, logger state, AWS, proxy-URL and keychain env, and session-end client cleanup now reset for unit tests too. The environment isolation owns its MonkeyPatch so a test's own monkeypatch is undone before the model-cost teardown runs. * test: merge, split and prune the moved root and small-tree tests Merge batches/test_batch_utils.py and the chat_completions and messages dispatch tests into the files that already existed in tests/unit. Keep the live Gemini interactions tests, the async image-fetch format test and the OpenAI embedding scorer test in tests/test_litellm since they need real network or keys. Put test_router.py under tests/unit/test_router so the existing package no longer shadows it. Delete eight tests the audit found superseded by stronger ones kept in this move. * ci: run the moved root and small-tree tests under their legacy flags Add the misc and responses-caching-types flags to unit_selection.sh and CircleCI, extend enterprise-routing and mcp-integration, and point the legacy GHA shards, Makefile, redis-compat workflow, merge smoke manifest and change classifier at the new paths. * test: make the new tests/unit directories packages tests/unit/test_package_layout.py requires every directory to carry an __init__.py, and without one the moved and retained test_litellm_responses_bridge.py modules collide on import. * test: scope the unit socket block to tests/unit in shared sessions The GHA shards collect the legacy test-path and the unit selection in one pytest session. The unit conftest's loopback-only block leaked into legacy modules that reach the network at import. The legacy conftest now lifts the restriction at collect and setup time, and the unit conftest re-applies it when collecting its own modules. * test: move tests/test_litellm/llms into tests/unit/llms Rename-only. Moves the provider tests and the fine-tuning fixtures they load, mirroring the old paths. Follow-up commits merge, split and wire them. * test: merge, split and prune the moved llms tests Merges the Databricks chat transformation tests into the existing unit file, keeps the tests that need real keys or the network in tests/test_litellm, deletes the audited tests a stronger unit test already covers, and points imports at tests.unit.llms. * ci: run the moved llms tests under their legacy flags The Vertex AI and All Other Providers shards keep their legacy test-path for the retained files and add the llm-vertex-ai and llm-other-providers unit selections. CircleCI gets matching unit jobs. * test: make the tests/unit/llms directories packages Adds __init__.py to the moved dirs and drops the legacy ones whose directories no longer hold tests. * test: drop script runners and path hacks the llms split left dangling The __main__ runners in the split openai_like files and the Databricks e2e runner called tests that now live in the other half of the split or were deleted. The retained legacy halves also no longer need sys.path edits. * test: give the shard-script tests their own GITHUB_OUTPUT They only passed where the runner set it. The CircleCI unit job's env allowlist drops it, so the script's redirect failed there. * test: point the router and module-deletion checks at tests/unit router_code_coverage and code_qa_check_tests only searched tests/test_litellm, so the moved router tests no longer counted. The two silent-experiment tests the audit deleted were the only direct callers of those methods; they are replaced with tests that assert the forwarded shadow request and the recursion guard. * test: move tests/test_litellm integrations and secret_managers into tests/unit Rename-only. Mirrors the old paths, including the directory conftests and the prompt and JSON fixtures. Follow-up commits prune and wire them. * test: prune and repoint the moved integrations tests Deletes the 7 audited tests a stronger test in the same tree already covers, imports the TLS sink helpers from their new conftest path, and restores os.environ after each integrations test. Some presets write OTEL_EXPORTER_OTLP_HEADERS straight into os.environ, and without the legacy tree's test ordering that header leaked into the AgentOps tests. * ci: run the moved integrations tests under their legacy flag The integrations GHA shard and a new CircleCI job run the integrations unit selection. secret_managers joins the misc selection. * docs: point integrations and secret_managers references at tests/unit * test: make the moved integrations directories packages * test: keep the Databricks manual e2e runner and fix the SageMaker Nova run path The Databricks e2e file is a manual script whose main() calls the tests that were pruned, so pruning them broke the documented run. It is back to its main version. The SageMaker Nova docstring now points at the file's real location in tests/local_testing. * test: keep the job's UNIT_FLAG out of the shard-script tests --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> (cherry picked from commit cf491d1) * fix(tests): drop the repeated UNIT_FLAG key in test_unit_shard_missing_paths (#43212) Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com> (cherry picked from commit 25de1ab) * fix(jwt): let x-litellm-team-id select DB membership teams when the token also carries a team claim (#43206) * fix(jwt): let x-litellm-team-id select DB membership teams when the token also carries a team claim Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * docs(jwt): describe header team selection under fallback_to_db_teams Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: yassin <yassin@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> (cherry picked from commit 7b4fd47) * test: move tests/test_litellm core utils, routing, responses, caching and rust_bridge into tests/unit (#43199) * ci: run the unit_selection.sh shard files on every event instead of only fork pull requests Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * ci: rename fork-flag to unit-flag now that it applies on every event * test: move tests/test_litellm root and small trees into tests/unit Pure renames, no content changes. Follow-up commits in this PR fix references, merge the three files that already existed in tests/unit, keep live-provider tests in tests/test_litellm and wire CI. * test: carry tests/test_litellm conftest isolation into tests/unit Callback lists, routing fallbacks, cached HTTP clients, logger state, AWS, proxy-URL and keychain env, and session-end client cleanup now reset for unit tests too. The environment isolation owns its MonkeyPatch so a test's own monkeypatch is undone before the model-cost teardown runs. * test: merge, split and prune the moved root and small-tree tests Merge batches/test_batch_utils.py and the chat_completions and messages dispatch tests into the files that already existed in tests/unit. Keep the live Gemini interactions tests, the async image-fetch format test and the OpenAI embedding scorer test in tests/test_litellm since they need real network or keys. Put test_router.py under tests/unit/test_router so the existing package no longer shadows it. Delete eight tests the audit found superseded by stronger ones kept in this move. * ci: run the moved root and small-tree tests under their legacy flags Add the misc and responses-caching-types flags to unit_selection.sh and CircleCI, extend enterprise-routing and mcp-integration, and point the legacy GHA shards, Makefile, redis-compat workflow, merge smoke manifest and change classifier at the new paths. * test: make the new tests/unit directories packages tests/unit/test_package_layout.py requires every directory to carry an __init__.py, and without one the moved and retained test_litellm_responses_bridge.py modules collide on import. * test: scope the unit socket block to tests/unit in shared sessions The GHA shards collect the legacy test-path and the unit selection in one pytest session. The unit conftest's loopback-only block leaked into legacy modules that reach the network at import. The legacy conftest now lifts the restriction at collect and setup time, and the unit conftest re-applies it when collecting its own modules. * test: move tests/test_litellm/llms into tests/unit/llms Rename-only. Moves the provider tests and the fine-tuning fixtures they load, mirroring the old paths. Follow-up commits merge, split and wire them. * test: merge, split and prune the moved llms tests Merges the Databricks chat transformation tests into the existing unit file, keeps the tests that need real keys or the network in tests/test_litellm, deletes the audited tests a stronger unit test already covers, and points imports at tests.unit.llms. * ci: run the moved llms tests under their legacy flags The Vertex AI and All Other Providers shards keep their legacy test-path for the retained files and add the llm-vertex-ai and llm-other-providers unit selections. CircleCI gets matching unit jobs. * test: make the tests/unit/llms directories packages Adds __init__.py to the moved dirs and drops the legacy ones whose directories no longer hold tests. * test: drop script runners and path hacks the llms split left dangling The __main__ runners in the split openai_like files and the Databricks e2e runner called tests that now live in the other half of the split or were deleted. The retained legacy halves also no longer need sys.path edits. * test: give the shard-script tests their own GITHUB_OUTPUT They only passed where the runner set it. The CircleCI unit job's env allowlist drops it, so the script's redirect failed there. * test: point the router and module-deletion checks at tests/unit router_code_coverage and code_qa_check_tests only searched tests/test_litellm, so the moved router tests no longer counted. The two silent-experiment tests the audit deleted were the only direct callers of those methods; they are replaced with tests that assert the forwarded shadow request and the recursion guard. * test: move tests/test_litellm integrations and secret_managers into tests/unit Rename-only. Mirrors the old paths, including the directory conftests and the prompt and JSON fixtures. Follow-up commits prune and wire them. * test: prune and repoint the moved integrations tests Deletes the 7 audited tests a stronger test in the same tree already covers, imports the TLS sink helpers from their new conftest path, and restores os.environ after each integrations test. Some presets write OTEL_EXPORTER_OTLP_HEADERS straight into os.environ, and without the legacy tree's test ordering that header leaked into the AgentOps tests. * ci: run the moved integrations tests under their legacy flag The integrations GHA shard and a new CircleCI job run the integrations unit selection. secret_managers joins the misc selection. * docs: point integrations and secret_managers references at tests/unit * test: make the moved integrations directories packages * test: keep the Databricks manual e2e runner and fix the SageMaker Nova run path The Databricks e2e file is a manual script whose main() calls the tests that were pruned, so pruning them broke the documented run. It is back to its main version. The SageMaker Nova docstring now points at the file's real location in tests/local_testing. * test: move tests/test_litellm core utils, routing, responses, caching and rust_bridge into tests/unit Rename-only. Mirrors the old paths, including fixtures, the stubtest config and the native-route wheel script. Two files that collide with existing unit files are merged in a follow-up commit. * test: merge, prune and repoint the moved core, routing, responses, caching and rust_bridge tests Merges the two files that collided with existing unit files, folding the legacy extra case into test_is_chat_completion_cached_dict, and deletes the 9 audited tests a stronger test in the same file already covers. Keeps what needs the network in tests/test_litellm: test_tokenizers pulls a tokenizer from the Hugging Face hub, and the gpt2 and r50k_base tokenizer cases download their BPE files. The unit core_utils conftest points TIKTOKEN_CACHE_DIR at litellm's bundled encodings so the rest never depend on import order to stay offline, and FakeSecretVault moves to a shared module so both trees can build it. * ci: run the moved core, routing, responses, caching and rust_bridge tests under their flags core_utils gets a core-utils flag and CircleCI job, and its GHA shard keeps the legacy path for the retained network tests. router_utils and router_strategy join enterprise-routing, responses joins responses-caching-types (minus responses/mcp, which mcp-integration owns), caching joins caching-local and rust_bridge joins misc. The redis-compat, test-rust, stubtest and merge-smoke paths follow the move. * docs: point the Rust crate references at tests/unit * test: make the moved core, routing and rust_bridge directories packages * test: keep the no-loop DualCache batch_get_cache regression test It runs the sync path outside any event loop, which the inside-loop test cannot, so a change that picks the Redis client by loop state would only show up there. * test: keep the job's UNIT_FLAG out of the shard-script tests * fix(url_utils): block 192.0.0.0/24 on every Python patch release * test: move the new budget limiter tests into tests/unit/router_strategy * test: move the new sentry scrubbing tests into tests/unit/litellm_core_utils * test: move the new zerobus tests into tests/unit/integrations * test: make tests/unit/integrations/zerobus a package * test: load litellm's own tiktoken cache setup once instead of resetting it per test --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> (cherry picked from commit a11a93f) * refactor(rust): move credential inheritance and the SDK limits out of the legacy callback crate into a driver preflight (#43259) The legacy callback crate carried two rewrites that have nothing to do with the Logging contract: litellm_credential_name inheritance and the max_budget and num_retries_per_request checks. Any later callback host would need them unchanged, which is the smell the crate's AGENTS.md now names. They are now a Preflight the driver in litellm-host-python runs on the keyword view begin returned, before the host projects from it, supplied by python-bridge and passed through run_legacy_call. The call order is unchanged (setup, deployment hook, credentials, limits) and a rejection still fails the call as a host failure, so the failure callbacks run as before. The preflight rewrites the adapter's own copy in place, so no extra dict copy and no new lifecycle method Co-authored-by: Yujong Lee <yujong@berri.ai> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> (cherry picked from commit e9491d3) * refactor(http): hand out an owned Client and route all providers through the pool (#43245) * refactor(messages): take the provider client from the injected HTTP pool The messages route kept its own process-wide reqwest client, so it ignored ssl_verify, CA bundles, client certs, proxies and every other setting that litellm-http resolves. The machine now takes the HttpClientPool and the call's HttpClientConfig, as OCR does, and the bridge passes its shared pool. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * refactor(http): hand out an owned Client and move chat, audio and OIDC onto the pool HttpClientPool now returns litellm_http::Client, a newtype only crates/http can build, so every provider client carries the resolved TLS, proxy and timeout settings. Chat completions and audio transcription drop their process-wide reqwest clients and take the pool and call config like messages; their 600s ceiling moves to the request. OidcResolver takes its client instead of building one, and the bridge hands it the pooled one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * refactor(secrets): build Google, Azure and CyberArk manager clients from the pool The native secret managers built bare reqwest clients, so they ignored the host's TLS and proxy settings. load_native_manager now takes the pool and the host config and hands each manager a pooled client. CyberArk's CYBERARK_SSL_VERIFY and CYBERARK_CLIENT_CERT/KEY become an override on the host config instead of a hand-built client. To express a certificate and key in separate files, HttpClientConfig::client_certificate is now a ClientIdentity that is either one PEM or a split pair. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(clippy): only crates/http may build a reqwest client Fence reqwest::Client, ClientBuilder and the TLS builder methods with disallowed-types and disallowed-methods so new code takes a litellm_http::Client from the pool. crates/http is exempt as the one place clients are built, and testkit as a dev-only installer. Tests move to litellm_http::Client::plain_for_test or a pooled client. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(secrets-cyberark): keep verifying certificates when the host disables it Python hands CyberArk its own ssl_verify, which wins over the global setting, so CYBERARK_SSL_VERIFY unset or true still verifies even when the host sets ssl_verify false. The pooled client copied the host's Disabled and would send the API key unverified; fall back to the built-in roots instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(python-bridge): treat a missing litellm package as no host HTTP settings Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: Yujong Lee <yujong@berri.ai> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> (cherry picked from commit 1a58162) * refactor(rust): promote anthropic messages out of experimental_pass_through (#43269) Co-authored-by: Yujong Lee <yujong@berri.ai> (cherry picked from commit 2ef3250) * test: stop CI tests from downloading tokenizer files and images (#43257) * test: load the embedding base image from a committed 100x100 PNG instead of downloading it * test: move the volcengine embedding test into tests/unit * test: check gpt2 and r50k_base tokenizer parity against committed tiktoken reference files * test: check hub tokenizer selection against an in-memory Hugging Face hub * test: serve image URLs from respx in the gemini tool-result and format-param tests * ci: drop the emptied legacy core-utils test path * test: cover the cohere and anthropic tokenizer paths in the hub tokenizer test * test: fetch every format-param image through respx and check its bytes reach the request * test: drop the gpt2 and r50k_base parity tests, which no litellm path uses * test: drop comments that restate assertions in the format-param test (cherry picked from commit 2530255) * fix(rust): preserve nested optional import failures (#43265) * fix(rust): preserve nested optional import failures Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * test(rust): restore Python modules after settings tests Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: Yujong Lee <yujong@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> (cherry picked from commit e1a9378) * fix(callbacks-legacy-python): traverse and release the retained headers dict (#43274) * fix(callbacks-legacy-python): traverse and release the retained headers dict LegacyLogging keeps the headers dict it hands to pre_call and post_call, but its traverse never reported that edge to the collector and close never dropped it. A cycle a callback builds through that dict could not be collected, and a closed call kept the dict alive until the driver dropped the whole adapter. Visit and clear headers like body, with regression tests for both * refactor(callbacks-legacy-python): move the test support module into its own file --------- Co-authored-by: Yujong Lee <yujong@berri.ai> (cherry picked from commit 4eb340a) * test(integration): port langfuse callbacks-in-db coverage to the local harness (#43282) * test(integration): port langfuse callbacks-in-db coverage to the local harness Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * test(integration): assert the langfuse db rows after the exported span Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: yuneng <yuneng@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> (cherry picked from commit e11c3f5) * test: finish the non-proxy half of tests/test_litellm (#43281) * test: move key-gated tests/test_litellm SDK tests into tests/llm_translation and drop empty folders * test: make token counter and health check unit tests run offline * ci: point unit shards, rust path filter, Makefile and docs at tests/unit * docs: fix stale test_litellm run paths in moved llm_translation tests * fix: correct databricks e2e sys.path depth and contributing example path --------- Co-authored-by: yuneng <yuneng@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> (cherry picked from commit 99655b6) * refactor(rust): prepare inference and auth foundations for the gateway (#43287) * refactor(rust): prepare inference and auth foundations * fix(rust): keep textract operations parsing from kebab-case model names Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: Yujong Lee <yujong@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> (cherry picked from commit 7ae721b) * feat(rust): add config router and gateway crates (#43289) Co-authored-by: Yujong Lee <yujong@berri.ai> (cherry picked from commit affb547) * test(integration): run the Langfuse DB-callback test on its own scratch database (#43288) * test(integration): run the Langfuse DB-callback test on its own scratch database The test from #43282 wrote success_callback=langfuse and the LANGFUSE_* env into the shared integration LiteLLM_Config. The suite's long-running gateway reloads that table and only ever adds callbacks, so it kept exporting to the test's closed Langfuse fake for the rest of the shard even after the rows were restored. The owned proxy now gets a scratch database, which also removes the snapshot/restore code. scratch_database moves into _support/database.py so test_cache_and_quota and this test share one copy, and the stock-config guard now checks the callback settings instead of the raw YAML text. * test(integration): include failure_callback in the stock-config Langfuse guard (cherry picked from commit dd63637) * refactor(rust): expand logging and test coverage across gateway and Anthropic messages (#43295) * refactor(rust): prepare inference and auth foundations * fix(rust): keep textract operations parsing from kebab-case model names Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * done * refactor(types): derive Anthropic beta string conversions with Strum * fix(anthropic): report missing max_tokens as a missing field * refactor(rust): type Anthropic messages headers and auth after the Python layout Delete anthropic/messages/headers.rs. Its OAuth handling, credential ladder and beta merging move to anthropic/common_utils.rs where Python keeps them (optionally_handle_anthropic_oauth, get_auth_header, _merge_beta_headers), and the feature beta injection becomes update_headers_with_anthropic_beta on the messages config, as in Python. The BaseAnthropicMessagesConfig impl is unchanged apart from the bodies of validate_environment and request_headers Beta values are now the AnthropicBeta enum and BetaSet, which sort, dedupe and comma-join by construction. Request params gain typed speed, tools and context_management through Recognized, so the beta logic matches on enums instead of string-comparing JSON. OauthToken parses the sk-ant-oat token once and the chat config shares that detection instead of its own copy Case-insensitive header helpers move next to has_header in litellm-http. One deliberate divergence: a Bearer-prefixed OAuth key configured through api_key or ANTHROPIC_API_KEY is sent with a single Bearer scheme, where Python would emit "Bearer Bearer" Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * done * fix(rust): repair test compilation and clippy failures resolve auth before building the outbound request in prepare tests, give the host hook tests their own error type, and drop the disallowed reqwest client and err().expect() from core tests Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: Yujong Lee <yujong@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> (cherry picked from commit 90873c4) * test(proxy_behavior): scope the management proxy fixture to its package so its spend monitor cannot race the spend tests (#43302) Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> (cherry picked from commit 115668f) * fix(ci): stop stale CI reds, keep unit tests off the host env, retry CyberArk policy conflicts (#43294) * fix(ci): stop five stale or flaky CI reds and retry CyberArk policy-load conflicts The Langfuse redaction unit test exports to a local OTLP capture instead of polling Langfuse Cloud through a recorded lookup. The passthrough worker-kill test only requires spend rows for requests the surviving worker served. The spend-routes sweep treats the intentional /spend/capture_rate 503 as expected. CyberArk retries a 409 policy load in Python, Rust and the e2e Conjur helper instead of reading it as "variable exists". The integration egress guard now matches the script's own cgroup, so it no longer blocks the CircleCI agent, which runs as the same user. * fix(ci): keep the policy-load backoff typed as float * fix(ci): retry CyberArk policy loads without blocking the event loop and tighten the worker-kill and Langfuse tests * fix(secrets): load CyberArk policy one request at a time per manager * test(secrets): pin that non-conflict CyberArk policy failures are not retried * test(unit): run tests/unit with only an allowlisted host environment CircleCI's unit job inherits every project env var, so real provider keys, REDIS_HOST, DATABASE_URL and AWS or Azure credentials reached tests that assume none are set. Locally, litellm's import-time load_dotenv did the same from any .env up the tree. The unit conftest now drops every variable outside a small allowlist and disables dotenv before litellm is imported. * test(e2e): name a failed search and the stuck batch status instead of misattributing them The websearch session test read an empty web_search_tool_result_error block as a successful search, so a failing search tool surfaced as a session billing bug. The batch cancellation timeout now reports the last status the proxy returned. * fix(ci): scrub the host environment per unit test instead of for the whole pytest process GHA shards run tests/unit next to other suites in one process, so the import-time scrub deleted MCP_TEST_PEER_PYTHON before tests/mcp_tests read it and the MCP upstream fell back to the SDK2 interpreter. The two websearch tests that called OpenAI and Perplexity live are removed: tests/unit no longer sees their keys. * fix(ci): scrub only the host variables present before litellm is imported The per-test scrub also deleted TIKTOKEN_CACHE_DIR, which litellm sets at import to its bundled encodings, so tokenizer paths tried to download them and hit the socket guard. The prisma setup test now passes its own database URL instead of reading one another test leaked into the process environment. * fix(ci): stop the order-dependent unit reds and settle logging tasks on their own queue LoggingWorker marked a task done on whichever queue was current when the callback finished, so a callback that outlived an event-loop change raised "task_done() called too many times" or undercounted the new loop's queue. It now settles the queue the task came from. The rest are test isolation fixes for failures that only appeared when another file ran first on the same xdist worker: a replaced user_api_key_cache, breaker metrics unregistered by prometheus tests, semantic_router's health-check filter on uvicorn.access, logging tasks carried over from bedrock tests, a Router-written model_cost entry, and a stray post captured by the langflow test. The token counter check now asserts bounded chunking instead of wall-clock time. * test(e2e/ui): wait for the logout redirect before visiting a protected page Logout revokes the session server-side before clearing cookies and navigating, so an immediate page.goto either ran with the cookie still set or was aborted by the logout redirect (net::ERR_ABORTED). * test(unit): restore the prometheus metrics config per test and settle logs carried from earlier tests in the a2a cost tests * test(router): pin the router clock in the usage counter tests so a minute rollover cannot empty the read * test(e2e/ui): wait for logout to clear the token cookie instead of for a login redirect * test(integration/mcp): answer the model-info probe another test's proxy sends to the model double (cherry picked from commit 14f4c34) * test(e2e): assert only litellm-owned batch behavior and move the blank S3 env pin to an integration test (#43321) (cherry picked from commit e53e67e) * ci: drop main and litellm_* branch filters from the CircleCI litellm-main workflows (#43272) Co-authored-by: yuneng <yuneng@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> (cherry picked from commit c822c7f) * test(e2e): accept the otel cost write as a linked root trace (#42931) * test(e2e): accept the otel cost write as a linked root trace Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * test(e2e): window and fail-closed the linked otel trace read-back Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * test(e2e): poll the otel read-back without recursion Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: yuneng <yuneng@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> (cherry picked from commit 3ebf6a1) * refactor(rust): exclude gateway and config crates from rc backport * refactor(rust): exclude router crate from rc backport --------- Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: Yujong Lee <yujong@berri.ai> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com> Co-authored-by: yassin <yassin@berri.ai>
…election to rc/1.103.0 (#43343) * feat(otel): emit gen_ai.conversation.id from the caller's session id on v2 LLM spans (#42486) * feat(otel): emit gen_ai.conversation.id from the caller's session id on v2 LLM spans Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(otel): keep the caller's header session under missing_session_id: generate and read replayed payload session ids Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(otel): drop only the proxy-minted session id so a caller id on the other metadata key survives Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(otel): keep a replayed session id hidden when it only echoes the payload trace id Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(otel): keep a replayed session id even when the payload trace id fell back to it Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(otel): stop reading the replayed payload's session id, the generated marker does not survive replay Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * test(integration): audit gen_ai.conversation.id on otel v2 spans through a real proxy, sink and postgres Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * test(integration): keep otel conversation rigs alive for the whole session so shuffled shards do not reboot the proxy per test Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * test(otel): stop the audit rig proxies from probing sibling test peers for model info Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * test(otel): record accepted OTLP batches in the sink instead of mutating the collector Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * test(otel): guard the accepted batch deque so snapshots cannot race sink appends Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: mrinal <mrinal@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: yucheng <yucheng@berri.ai> (cherry picked from commit a319690) * fix(jwt): accept a team alias in x-litellm-team-id (#42445) * fix(jwt): accept a team alias in x-litellm-team-id The header only matched canonical team ids, so a JWT caller selecting one of their teams by its alias got a 403 even though they belonged to it. The header value is now resolved through the existing alias lookup before the JWT allowed-team check and the DB membership fallback, while a value that is already a team id never costs an alias lookup and denials keep naming the value the caller sent Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(jwt): only alias a header team id the database provably lacks Under fallback_to_db_teams a header value whose team row read fails for any reason other than TeamNotFoundError now keeps the membership denial instead of falling through to the alias lookup, so a degraded read cannot select a different team that carries the value as an alias. Drops the HeaderTeam docstring that only restated its fields Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: ryan <ryan@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> (cherry picked from commit 071cb49) * fix(jwt): say x-litellm-team-id matched no team id or alias in the 403 (#42495) * fix(jwt): say x-litellm-team-id matched no team id or alias in the 403 Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(jwt): tell the caller when x-litellm-team-id names an alias shared by several teams Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(jwt): deny a shared x-litellm-team-id alias exactly like an unknown value A distinct 403 for an alias several teams share was raised before the allowed-teams check, so any JWT could probe which aliases exist. The alias lookup now treats the duplicate as a miss, and both denials say the value does not resolve to a team id or a unique team alias, which is true for unknown, unauthorized and duplicate values alike Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: ryan <ryan@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> (cherry picked from commit 08639fc) * fix(jwt): let x-litellm-team-id select DB membership teams when the token also carries a team claim (#43206) * fix(jwt): let x-litellm-team-id select DB membership teams when the token also carries a team claim Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * docs(jwt): describe header team selection under fallback_to_db_teams Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: yassin <yassin@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> (cherry picked from commit 7b4fd47) --------- Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: mrinal <mrinal@berri.ai> Co-authored-by: yucheng <yucheng@berri.ai> Co-authored-by: ryan <ryan@berri.ai> Co-authored-by: yassin <yassin@berri.ai>
…105.0) (#866) This PR contains the following updates: | Package | Update | Change | |---|---|---| | [ghcr.io/berriai/litellm](https://images.chainguard.dev/directory/image/wolfi-base/overview) ([source](https://github.com/BerriAI/litellm)) | minor | `v1.104.0` → `v1.105.0` | --- ### Release Notes <details> <summary>BerriAI/litellm (ghcr.io/berriai/litellm)</summary> ### [`v1.105.0`](https://github.com/BerriAI/litellm/releases/tag/v1.105.0) [Compare Source](https://github.com/BerriAI/litellm/compare/v1.104.3...v1.105.0) ##### Verify Docker Image Signature All LiteLLM Docker images are signed with [cosign](https://docs.sigstore.dev/cosign/overview/). Every release is signed with the same key introduced in [commit `0112e53`](https://github.com/BerriAI/litellm/commit/0112e53046018d726492c814b3644b7d376029d0). **Verify using the pinned commit hash (recommended):** A commit hash is cryptographically immutable, so this is the strongest way to ensure you are using the original signing key: ```bash cosign verify \ --key https://raw.githubusercontent.com/BerriAI/litellm/0112e53046018d726492c814b3644b7d376029d0/cosign.pub \ ghcr.io/berriai/litellm:v1.105.0 ``` **Verify using the release tag (convenience):** Tags are protected in this repository and resolve to the same key. This option is easier to read but relies on tag protection rules: ```bash cosign verify \ --key https://raw.githubusercontent.com/BerriAI/litellm/v1.105.0/cosign.pub \ ghcr.io/berriai/litellm:v1.105.0 ``` Expected output: ``` The following checks were performed on each of these signatures: - The cosign claims were validated - The signatures were verified against the specified public key ``` *** ##### What's Changed - feat(mcp): share compatibility-aware result conversion across tool surfaces by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43089](https://github.com/BerriAI/litellm/pull/43089) - fix(caching): propagate auth cache invalidation over Redis Cluster via a node-level pub/sub client by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43110](https://github.com/BerriAI/litellm/pull/43110) - feat(model-catalog): add Rust registry validation by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43136](https://github.com/BerriAI/litellm/pull/43136) - test(rust): reorganize core crate tests and split cache and OCR suites by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43177](https://github.com/BerriAI/litellm/pull/43177) - fix(proxy): give SpendLogToolIndex its own share of the cleanup budget and log a per-run summary by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​41768](https://github.com/BerriAI/litellm/pull/41768) - feat(rust): hand upstream response headers to the native Messages stream by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43178](https://github.com/BerriAI/litellm/pull/43178) - feat(testkit): agent clients for Claude Code, Codex and opencode by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43181](https://github.com/BerriAI/litellm/pull/43181) - ci: run migrated unit selections on every event in legacy GHA shards by [@​yuneng-berri](https://github.com/yuneng-berri) in [#​43182](https://github.com/BerriAI/litellm/pull/43182) - test: move tests/test_litellm root and small trees into tests/unit by [@​yuneng-berri](https://github.com/yuneng-berri) in [#​43186](https://github.com/BerriAI/litellm/pull/43186) - fix(sso): gate /sso/debug routes behind ENABLE_SSO_DEBUG, off by default by [@​ojensen-berri](https://github.com/ojensen-berri) in [#​43150](https://github.com/BerriAI/litellm/pull/43150) - refactor(framer): replace Framer trait with tokio-util codecs by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43193](https://github.com/BerriAI/litellm/pull/43193) - fix(anthropic): surface Responses bridge stream failures as Anthropic error events by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43126](https://github.com/BerriAI/litellm/pull/43126) - test: move tests/test_litellm/llms into tests/unit/llms by [@​yuneng-berri](https://github.com/yuneng-berri) in [#​43191](https://github.com/BerriAI/litellm/pull/43191) - test: move tests/test_litellm integrations and secret_managers into tests/unit by [@​yuneng-berri](https://github.com/yuneng-berri) in [#​43194](https://github.com/BerriAI/litellm/pull/43194) - feat(mcp): configure protocol versions and capability discovery by [@​joshua-berri](https://github.com/joshua-berri) in [#​43169](https://github.com/BerriAI/litellm/pull/43169) - fix(proxy): record streamed /v1/responses container ownership before the response.completed frame by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43140](https://github.com/BerriAI/litellm/pull/43140) - fix(tests): drop the repeated UNIT_FLAG key in test_unit_shard_missing_paths by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43212](https://github.com/BerriAI/litellm/pull/43212) - fix(router): count provider budget spend on every API surface by [@​daqiangganjun](https://github.com/daqiangganjun) in [#​38172](https://github.com/BerriAI/litellm/pull/38172) - fix(responses): fall back on pre-output stream drops, fail truncated streams, honor request_timeout by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43133](https://github.com/BerriAI/litellm/pull/43133) - fix(sentry): scrub PII and secrets inside object reprs and nested locals, add SENTRY_SEND_DEFAULT_PII opt-in by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43123](https://github.com/BerriAI/litellm/pull/43123) - fix(bedrock): surface a converse-stream 200 that decodes to no events as a 502 instead of an empty turn by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43213](https://github.com/BerriAI/litellm/pull/43213) - fix(jwt): let x-litellm-team-id select DB membership teams when the token also carries a team claim by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43206](https://github.com/BerriAI/litellm/pull/43206) - feat(integrations): add Databricks Zerobus trace logging callback by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​42013](https://github.com/BerriAI/litellm/pull/42013) - fix(vertex_ai): keep legacy bucket_name in credential resolution and add GCS_BATCH_BUCKET_NAME env var by [@​mubashir1osmani](https://github.com/mubashir1osmani) in [#​42803](https://github.com/BerriAI/litellm/pull/42803) - feat(xai): add native xAI batches and files support by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​42812](https://github.com/BerriAI/litellm/pull/42812) - fix(proxy): send a real error event when a /v1/messages stream fails by [@​4refael](https://github.com/4refael) in [#​41826](https://github.com/BerriAI/litellm/pull/41826) - fix(logging): redact raw_request when turn_off_message_logging is set in the proxy config by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43219](https://github.com/BerriAI/litellm/pull/43219) - fix(router): parse the classifier verdict out of surrounding prose instead of falling to the default tier by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43215](https://github.com/BerriAI/litellm/pull/43215) - test(zerobus): move tests into active CI selection by [@​tin-berri](https://github.com/tin-berri) in [#​43235](https://github.com/BerriAI/litellm/pull/43235) - fix(proxy): keep the submitted body out of 422 validation errors by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43231](https://github.com/BerriAI/litellm/pull/43231) - test: move tests/test_litellm core utils, routing, responses, caching and rust_bridge into tests/unit by [@​yuneng-berri](https://github.com/yuneng-berri) in [#​43199](https://github.com/BerriAI/litellm/pull/43199) - chore(cost-map): add fireworks us-only deepseek v4.1 flash priority prices by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43247](https://github.com/BerriAI/litellm/pull/43247) - chore(cost-map): sync openrouter prices and add perceptron-mk1.5 by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43246](https://github.com/BerriAI/litellm/pull/43246) - fix(cost-map): correct fireworks_ai deepseek-v4p1-flash pricing by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43253](https://github.com/BerriAI/litellm/pull/43253) - feat(openrouter): add typesafe/jev-router to the cost map by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43248](https://github.com/BerriAI/litellm/pull/43248) - chore(cost-map): add fireworks priority prices for muse glimmer 30b and deepseek v4 flash vision exp by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43252](https://github.com/BerriAI/litellm/pull/43252) - refactor(rust): move credential inheritance and SDK limits into a driver preflight by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43259](https://github.com/BerriAI/litellm/pull/43259) - fix(router): hold Responses lifecycle events until output so a pre-output fallback announces one response by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43238](https://github.com/BerriAI/litellm/pull/43238) - refactor(http): hand out an owned Client and route all providers through the pool by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43245](https://github.com/BerriAI/litellm/pull/43245) - test: fix stale and state-leaking tests red on scheduled CircleCI by [@​yuneng-berri](https://github.com/yuneng-berri) in [#​43266](https://github.com/BerriAI/litellm/pull/43266) - fix(cost-map): retirement dates, chatgpt reasoning flags, bing pricing, bedrock mantle and mythos, azure gpt-5.6 alias, anthropic batch rates, new nebius, openrouter and xai rows by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​42951](https://github.com/BerriAI/litellm/pull/42951) - refactor(rust): promote anthropic messages out of experimental_pass_through by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43269](https://github.com/BerriAI/litellm/pull/43269) - test: stop CI tests from downloading tokenizer files and images by [@​yuneng-berri](https://github.com/yuneng-berri) in [#​43257](https://github.com/BerriAI/litellm/pull/43257) - fix(rust): preserve nested optional import failures by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43265](https://github.com/BerriAI/litellm/pull/43265) - ci: drop main and litellm\_\* branch filters from the CircleCI litellm-main workflows by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43272](https://github.com/BerriAI/litellm/pull/43272) - feat(proxy): email alerts at configured percentages of a team member budget by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​42665](https://github.com/BerriAI/litellm/pull/42665) - fix(callbacks-legacy-python): traverse and release the retained headers dict by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43274](https://github.com/BerriAI/litellm/pull/43274) - test(integration): port langfuse callbacks-in-db coverage to the local harness by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43282](https://github.com/BerriAI/litellm/pull/43282) - test(e2e): accept the otel cost write as a linked root trace by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​42931](https://github.com/BerriAI/litellm/pull/42931) - test: finish the non-proxy half of tests/test_litellm by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43281](https://github.com/BerriAI/litellm/pull/43281) - refactor(rust): prepare inference and auth foundations for the gateway by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43287](https://github.com/BerriAI/litellm/pull/43287) - feat(rust): add config, router and gateway crates by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43289](https://github.com/BerriAI/litellm/pull/43289) - fix(cost-map): remove duplicate openrouter/perceptron/perceptron-mk1.5 entry by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43273](https://github.com/BerriAI/litellm/pull/43273) - fix(e2e): resolve the blank-S3 gateway repo root from the litellm package location by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​42911](https://github.com/BerriAI/litellm/pull/42911) - test(integration): run the Langfuse DB-callback test on its own scratch database by [@​yuneng-berri](https://github.com/yuneng-berri) in [#​43288](https://github.com/BerriAI/litellm/pull/43288) - refactor(rust): expand logging and test coverage across gateway and Anthropic messages by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43295](https://github.com/BerriAI/litellm/pull/43295) - refactor: daily fresh tech debt cleanup, rolling PR (2026-09-25) by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43151](https://github.com/BerriAI/litellm/pull/43151) - test(proxy_behavior): scope the management proxy fixture to its package so its spend monitor cannot race the spend tests by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43302](https://github.com/BerriAI/litellm/pull/43302) - fix(cost-map): registry audit 2026-09-26, MAI-Image-2.5-Flash price, Databricks Claude Opus 5.5, Azure Foundry retirement dates by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43254](https://github.com/BerriAI/litellm/pull/43254) - fix(cost-map): price fireworks deepseek v4.1 flash at the prices api value by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43311](https://github.com/BerriAI/litellm/pull/43311) - fix(ci): stop stale CI reds, keep unit tests off the host env, retry CyberArk policy conflicts by [@​yuneng-berri](https://github.com/yuneng-berri) in [#​43294](https://github.com/BerriAI/litellm/pull/43294) - fix(otel): detach post-response service spans by request phase, name redis spans by operation by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43237](https://github.com/BerriAI/litellm/pull/43237) - test(e2e): assert only litellm-owned batch behavior and move the blank S3 env pin to an integration test by [@​yuneng-berri](https://github.com/yuneng-berri) in [#​43321](https://github.com/BerriAI/litellm/pull/43321) - test(integration): pin the team-admin status-code matrix across every management route by [@​ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#​43249](https://github.com/BerriAI/litellm/pull/43249) - feat(proxy): add fail_closed_rate_limit_enforcement to reject requests with 503 while Redis rate limit counters are unreachable by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43251](https://github.com/BerriAI/litellm/pull/43251) - fix(responses): run stream failure and success hooks on the iterating loop instead of blocking it by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43270](https://github.com/BerriAI/litellm/pull/43270) - fix(guardrails): block private destinations in custom code http_request and bound guardrail execution time by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43280](https://github.com/BerriAI/litellm/pull/43280) - feat(sail): add Sail as a provider with service_tier mapped to its completion window by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​42840](https://github.com/BerriAI/litellm/pull/42840) - test(mcp): pin server resolution and authorization behavior by [@​joshua-berri](https://github.com/joshua-berri) in [#​43261](https://github.com/BerriAI/litellm/pull/43261) - refactor(anthropic): rename experimental_pass_through to pass_through by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43329](https://github.com/BerriAI/litellm/pull/43329) - refactor(mcp): add shared server resolver without changing callers by [@​joshua-berri](https://github.com/joshua-berri) in [#​43262](https://github.com/BerriAI/litellm/pull/43262) - ci: fail on new unbounded SQL IN lists and add a Prisma chunking helper by [@​ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#​42629](https://github.com/BerriAI/litellm/pull/42629) - test(logging): drain the logging worker after each logging callback test so no later test inherits its events by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43344](https://github.com/BerriAI/litellm/pull/43344) - feat(guardrails): scan retrieved vector store chunks with the request's pre-call guardrails by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43271](https://github.com/BerriAI/litellm/pull/43271) - fix(mcp): adopt shared server resolution and caller authorization by [@​joshua-berri](https://github.com/joshua-berri) in [#​43263](https://github.com/BerriAI/litellm/pull/43263) - fix(s3_v2): upload fresh events first, drop terminal failures and hour-old retries by default, opt-in adaptive concurrency by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43022](https://github.com/BerriAI/litellm/pull/43022) - feat(proxy): add maximum_daily_tag_spend_retention_period cleanup setting by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​39221](https://github.com/BerriAI/litellm/pull/39221) - fix(cost-map): sync OpenRouter, Together, Cohere and Azure AI registry values with official sources by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43337](https://github.com/BerriAI/litellm/pull/43337) - docs(pr-template): add the backport-stable label only for a P0 regression by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43351](https://github.com/BerriAI/litellm/pull/43351) - fix(params): keep *litellm*\* kwargs out of provider request bodies by construction by [@​shrey-berri](https://github.com/shrey-berri) in [#​43221](https://github.com/BerriAI/litellm/pull/43221) - test: remove substring guard test_default_api_base by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43355](https://github.com/BerriAI/litellm/pull/43355) - ci: cut CircleCI wall time without loosening test isolation by [@​yuneng-berri](https://github.com/yuneng-berri) in [#​43347](https://github.com/BerriAI/litellm/pull/43347) - fix(cost-map): correct azure gpt-4o-mini tts, transcribe, alias and MAI-Image-2.5 prices by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43357](https://github.com/BerriAI/litellm/pull/43357) - fix(tests): stop VCR recording and replaying a test's own localhost upstream by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43346](https://github.com/BerriAI/litellm/pull/43346) - test(integration): group /v1/messages contracts under tests/integration/messages_endpoint by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43352](https://github.com/BerriAI/litellm/pull/43352) - fix(params): validate stream_chunk_size once, before any provider call by [@​shrey-berri](https://github.com/shrey-berri) in [#​43222](https://github.com/BerriAI/litellm/pull/43222) - fix(openai): exclude fine-tuned and custom gpt-5-chat aliases from gpt-5 reasoning path by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43185](https://github.com/BerriAI/litellm/pull/43185) - fix(langtrace): deliver spans to app.langtrace.ai/api/trace with x-api-key by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43322](https://github.com/BerriAI/litellm/pull/43322) - fix(caching): stand default cache points down when extra_body hides a direct client mark by [@​yuneng-berri](https://github.com/yuneng-berri) in [#​43341](https://github.com/BerriAI/litellm/pull/43341) - fix(mcp): report reachability without stored credentials by [@​tin-berri](https://github.com/tin-berri) in [#​43240](https://github.com/BerriAI/litellm/pull/43240) - fix(mcp): align hub publication status and controls by [@​tin-berri](https://github.com/tin-berri) in [#​43241](https://github.com/BerriAI/litellm/pull/43241) - chore(cost-map): sync openrouter prices for deepseek, minimax, qwen and glm rows by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43384](https://github.com/BerriAI/litellm/pull/43384) - chore(cost-map): drop stale cache hit field from openrouter deepseek-v4-pro-0813 by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43389](https://github.com/BerriAI/litellm/pull/43389) - fix(responses): stream guardrail pre-call block as SSE with a typed output item by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​42507](https://github.com/BerriAI/litellm/pull/42507) - feat(e2e): read management routes back from the control plane replicas by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43373](https://github.com/BerriAI/litellm/pull/43373) - feat(rust): add the openai_like chat config foundation by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43379](https://github.com/BerriAI/litellm/pull/43379) - feat(router): opt in to prompt-cache cost routing by [@​tin-berri](https://github.com/tin-berri) in [#​43232](https://github.com/BerriAI/litellm/pull/43232) - feat(otel): add SigNoz preset for OpenTelemetry v2 by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43296](https://github.com/BerriAI/litellm/pull/43296) - feat(cli): reuse saved agent setup and add reconfigure by [@​tin-berri](https://github.com/tin-berri) in [#​43392](https://github.com/BerriAI/litellm/pull/43392) - fix(streaming): keep litellm Usage on text-completion usage chunks by [@​yuneng-berri](https://github.com/yuneng-berri) in [#​43047](https://github.com/BerriAI/litellm/pull/43047) - fix(vertex_ai): consider tools when validating context caching min tokens by [@​agustin18](https://github.com/agustin18) in [#​43319](https://github.com/BerriAI/litellm/pull/43319) - fix(anthropic): drop thinking blocks with empty thinking text, not just missing signature by [@​shoemoney](https://github.com/shoemoney) in [#​38049](https://github.com/BerriAI/litellm/pull/38049) - test(e2e): report batch cleanup leftovers as a plain UserWarning by [@​yuneng-berri](https://github.com/yuneng-berri) in [#​43405](https://github.com/BerriAI/litellm/pull/43405) - fix(tools): salvage concatenated JSON tool call arguments by [@​kumarpriyanshu09](https://github.com/kumarpriyanshu09) in [#​43260](https://github.com/BerriAI/litellm/pull/43260) - fix(gemini): forward seed to the Gemini API instead of rejecting it by [@​YaseenBashaT](https://github.com/YaseenBashaT) in [#​43197](https://github.com/BerriAI/litellm/pull/43197) - fix(vertex_ai): make Gemma fake streams work with traced Responses by [@​stewartpark](https://github.com/stewartpark) in [#​43147](https://github.com/BerriAI/litellm/pull/43147) - fix(responses): emit the reasoning item on streaming /v1/responses for signature-only thinking by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43414](https://github.com/BerriAI/litellm/pull/43414) - fix(anthropic): forward the per-turn-control beta to Azure AI Foundry by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43415](https://github.com/BerriAI/litellm/pull/43415) - test(vertex_ai): assert the usage the Gemma responses stream actually reports by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43422](https://github.com/BerriAI/litellm/pull/43422) - fix(bedrock): keep the provider status code on unprocessable image errors by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43416](https://github.com/BerriAI/litellm/pull/43416) - fix(vertex_ai): stop importing the vertexai SDK in partner-model completion by [@​anmolg1997](https://github.com/anmolg1997) in [#​42274](https://github.com/BerriAI/litellm/pull/42274) - fix(token_counter): count Gemini function_declarations tools by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43417](https://github.com/BerriAI/litellm/pull/43417) - refactor(types): replace Any with proven types in 5 files by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43304](https://github.com/BerriAI/litellm/pull/43304) - chore(cost-map): update azure_ai/grok-4.6 input price from Azure pricing page by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43440](https://github.com/BerriAI/litellm/pull/43440) - chore(cost-map): add azure_ai/MAI-Cyber-1-Flash by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43446](https://github.com/BerriAI/litellm/pull/43446) - refactor(rust): share anthropic types, request helpers, and streaming contracts across crates by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43426](https://github.com/BerriAI/litellm/pull/43426) - feat(rust): expand gateway configuration parsing by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43460](https://github.com/BerriAI/litellm/pull/43460) - refactor(rust): share call lifecycle across route-owned inference by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43461](https://github.com/BerriAI/litellm/pull/43461) - feat(rust): add the HTTP host driver by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43462](https://github.com/BerriAI/litellm/pull/43462) - build(rust): package the gateway container by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43471](https://github.com/BerriAI/litellm/pull/43471) - refactor(rust): use shared execution in gateway inference by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43463](https://github.com/BerriAI/litellm/pull/43463) - fix(cost-map): add deprecation_date to together_ai Salesforce/Llama-Rank-V1 by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43507](https://github.com/BerriAI/litellm/pull/43507) - feat(rust): support the HTTP Responses API by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43464](https://github.com/BerriAI/litellm/pull/43464) - fix(cost-map): sync openrouter prices from the models API by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43506](https://github.com/BerriAI/litellm/pull/43506) - fix(cost-map): set together_ai gpt-oss-20b and gemma-4-31B-it deprecation_date to 2026-09-15 by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43509](https://github.com/BerriAI/litellm/pull/43509) - feat(rust): add litellm-db and litellm-db-testing workspace scaffolding by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43504](https://github.com/BerriAI/litellm/pull/43504) - feat(rust): connect Python inference bindings to shared routes by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43465](https://github.com/BerriAI/litellm/pull/43465) - feat(rust): add structured route lifecycle tracing by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43466](https://github.com/BerriAI/litellm/pull/43466) - feat(rust): separate gateway authentication and authorization by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43467](https://github.com/BerriAI/litellm/pull/43467) - feat(rust): add virtual key storage contracts by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43468](https://github.com/BerriAI/litellm/pull/43468) - feat(rust): add gateway UI login and sessions by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43469](https://github.com/BerriAI/litellm/pull/43469) - feat(rust): add the MCP gateway by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43470](https://github.com/BerriAI/litellm/pull/43470) - refactor(rust): remove delivery routing abstraction by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43514](https://github.com/BerriAI/litellm/pull/43514) - feat(azure): add mistral ocr pricing and azure max output limits by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43530](https://github.com/BerriAI/litellm/pull/43530) - refactor: clean up fresh tech debt from 2026-09-27 by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43538](https://github.com/BerriAI/litellm/pull/43538) - refactor(types): replace Any with proven types in 8 files by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43551](https://github.com/BerriAI/litellm/pull/43551) - test(rust): enforce shared upstream error contract in wheel checks by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43520](https://github.com/BerriAI/litellm/pull/43520) - fix(proxy): log key owner identity on expired key auth failures by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43105](https://github.com/BerriAI/litellm/pull/43105) - fix(cost-map): registry audit 2026-09-28, openai deep-research shutdown dates, azure deepseek v4.1 flash direct price, vertex gemini 3.8 live avatar price, drop azure_ai/muse-spark-1.3 by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43566](https://github.com/BerriAI/litellm/pull/43566) - security(proxy): keep team callback credentials out of the stored request body by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43217](https://github.com/BerriAI/litellm/pull/43217) - feat(model_prices): add claude-sonnet-5-5 model pricing by [@​krrish-berri-2](https://github.com/krrish-berri-2) in [#​43586](https://github.com/BerriAI/litellm/pull/43586) - test(integration): pin org-admin status codes in the team-admin matrix by [@​ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#​43592](https://github.com/BerriAI/litellm/pull/43592) - refactor(guardrails): fix agent 365 to the production endpoint and log the opt-in fail_open at error level by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43189](https://github.com/BerriAI/litellm/pull/43189) - fix(model_prices): correct Claude Sonnet 5.5 capabilities and provider keys by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43587](https://github.com/BerriAI/litellm/pull/43587) - test(unit): stop test modules from putting their own directory on sys.path by [@​yuneng-berri](https://github.com/yuneng-berri) in [#​43421](https://github.com/BerriAI/litellm/pull/43421) - refactor(rust): centralize host execution and compose callbacks by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43515](https://github.com/BerriAI/litellm/pull/43515) - fix(proxy): unregister logging callbacks removed from the stored config by [@​yuneng-berri](https://github.com/yuneng-berri) in [#​43428](https://github.com/BerriAI/litellm/pull/43428) - chore(cost-map): take azure limits for deepseek-v4-flash-0731 and v3.2-speciale by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43597](https://github.com/BerriAI/litellm/pull/43597) - revert: "feat(proxy): server-side Team Usage export beyond the top-N key cap ([#​42996](https://github.com/BerriAI/litellm/issues/42996))" by [@​yassin-berriai](https://github.com/yassin-berriai) in [#​43376](https://github.com/BerriAI/litellm/pull/43376) - fix(cost-map): add web search flag and model page source to anthropic claude-sonnet-5-5 by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43584](https://github.com/BerriAI/litellm/pull/43584) - refactor(mcp): consolidate hub publication predicate by [@​tin-berri](https://github.com/tin-berri) in [#​43394](https://github.com/BerriAI/litellm/pull/43394) - fix(provider): accept 2xx status codes in unified_access_group create by [@​Louis-Vauterin](https://github.com/Louis-Vauterin) in [#​42461](https://github.com/BerriAI/litellm/pull/42461) - fix(panw_prisma_airs): honor experimental_use_latest_role_message_only on every request shape by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​42447](https://github.com/BerriAI/litellm/pull/42447) - fix(cost-map): add Vertex batch cache prices to vertex_ai/claude-sonnet-5-5 by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43602](https://github.com/BerriAI/litellm/pull/43602) - revert: "feat(usage): search team keys beyond the top-N in the Team usage view ([#​42857](https://github.com/BerriAI/litellm/issues/42857))" by [@​yassin-berriai](https://github.com/yassin-berriai) in [#​43377](https://github.com/BerriAI/litellm/pull/43377) - feat(providers): add Prism provider (internal copy of [#​40914](https://github.com/BerriAI/litellm/issues/40914)) by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​41961](https://github.com/BerriAI/litellm/pull/41961) - test(integration): credential canary suite harness by [@​yucheng-berri](https://github.com/yucheng-berri) in [#​43300](https://github.com/BerriAI/litellm/pull/43300) - feat(bedrock): add xai grok-4.7 pricing and sync llama, mistral large 2407 and minimax m2.5 prices by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43623](https://github.com/BerriAI/litellm/pull/43623) - ci: sync the weekly release cycle with Linear releases by [@​yuneng-berri](https://github.com/yuneng-berri) in [#​43636](https://github.com/BerriAI/litellm/pull/43636) - feat(cache): select Rust caching through explicit cache objects by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43601](https://github.com/BerriAI/litellm/pull/43601) - test(integration): credential canary slots for MCP and pass-through credentials by [@​yucheng-berri](https://github.com/yucheng-berri) in [#​43308](https://github.com/BerriAI/litellm/pull/43308) - test(integration): stored-config credential canary slots by [@​yucheng-berri](https://github.com/yucheng-berri) in [#​43309](https://github.com/BerriAI/litellm/pull/43309) - fix(guardrails): preserve Presidio output selection and restoration by [@​joshua-berri](https://github.com/joshua-berri) in [#​43401](https://github.com/BerriAI/litellm/pull/43401) - fix(ui): rename All Models tab to Deployed Models and model filters to All Proxy Models by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43638](https://github.com/BerriAI/litellm/pull/43638) - feat(mcp): scan and pin upstream tool descriptions by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43283](https://github.com/BerriAI/litellm/pull/43283) - feat(cost-map): add bedrock_mantle rows for claude opus 5.5 and sonnet 5.5 by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43647](https://github.com/BerriAI/litellm/pull/43647) - chore(codeowners): drop UI, migration, and CODEOWNERS self owners by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43653](https://github.com/BerriAI/litellm/pull/43653) - feat(fireworks_ai): route and list the auto, auto-instant and firerouter routers by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43641](https://github.com/BerriAI/litellm/pull/43641) - feat: add model leaderboard page by [@​ishaan-berri](https://github.com/ishaan-berri) in [#​43649](https://github.com/BerriAI/litellm/pull/43649) - fix(google_genai): preserve proxy_server_request in completion adapter by [@​hsm207](https://github.com/hsm207) in [#​43536](https://github.com/BerriAI/litellm/pull/43536) - fix(otel): send cache and reasoning tokens in langfuse usage_details by [@​ankit373](https://github.com/ankit373) in [#​43553](https://github.com/BerriAI/litellm/pull/43553) - fix(vertex_ai): forward the per-turn-control beta for per-message output_config by [@​DeviaVir](https://github.com/DeviaVir) in [#​43558](https://github.com/BerriAI/litellm/pull/43558) - fix(cost-map): add tool calling and reasoning flags, correct max output for nebius DeepSeek-V4.1-Flash by [@​Flexomatic81](https://github.com/Flexomatic81) in [#​43588](https://github.com/BerriAI/litellm/pull/43588) - fix(proxy): resolve model_group_alias in the zero-cost budget predicate by [@​fedaeho](https://github.com/fedaeho) in [#​43512](https://github.com/BerriAI/litellm/pull/43512) - refactor: clean up fresh tech debt from 2026-09-28 by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43674](https://github.com/BerriAI/litellm/pull/43674) - refactor(types): replace Any with proven types in 7 files by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43704](https://github.com/BerriAI/litellm/pull/43704) - docs(security): point readers to the security announcements mailing list signup by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43713](https://github.com/BerriAI/litellm/pull/43713) - refactor(rust): add shared llms wire type derives by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43730](https://github.com/BerriAI/litellm/pull/43730) - fix(router): stream /v1/messages lifecycle frames live when no fallback can take over by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43600](https://github.com/BerriAI/litellm/pull/43600) - feat(cost-map): add baseten DeepSeek-V4.1-Flash-Fast by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43735](https://github.com/BerriAI/litellm/pull/43735) - feat(guardrails): send a configured gateway_name from noma_v2 to Noma by [@​itaimodi](https://github.com/itaimodi) in [#​43678](https://github.com/BerriAI/litellm/pull/43678) - chore(cost-map): add openai gpt-6.1-sol from the pricing page by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43738](https://github.com/BerriAI/litellm/pull/43738) - test(integration): callback credential canary slots C1-C3 and D5 by [@​yucheng-berri](https://github.com/yucheng-berri) in [#​43630](https://github.com/BerriAI/litellm/pull/43630) - test(integration): request-path credential canary slots D1-D4 by [@​yucheng-berri](https://github.com/yucheng-berri) in [#​43307](https://github.com/BerriAI/litellm/pull/43307) - test(integration): sweep proxy logs, metrics, a Datadog intake and the Logs drawer for credential canaries by [@​yucheng-berri](https://github.com/yucheng-berri) in [#​43306](https://github.com/BerriAI/litellm/pull/43306) - chore(cost-map): add azure and openrouter gpt-6.1-sol rows by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43744](https://github.com/BerriAI/litellm/pull/43744) - test(proxy): classify every credential-bearing param for the canary suite by [@​yucheng-berri](https://github.com/yucheng-berri) in [#​43298](https://github.com/BerriAI/litellm/pull/43298) - fix(cost-map): lower fireworks up-to-4b size tier to the pricing page price by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43740](https://github.com/BerriAI/litellm/pull/43740) - fix(cost_calculator): bill chat per-second pricing once with a new cost_per_second field by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43614](https://github.com/BerriAI/litellm/pull/43614) - chore(cost-map): add openai gpt-6-astra ultrafast tier prices from the pricing page by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43745](https://github.com/BerriAI/litellm/pull/43745) - fix(autorouter): compare historical and new savings consistently by [@​tin-berri](https://github.com/tin-berri) in [#​43348](https://github.com/BerriAI/litellm/pull/43348) - fix(model-prices): align Azure, Bedrock, Copilot, Gemini, Groq, OpenAI and OpenRouter entries with official docs by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43598](https://github.com/BerriAI/litellm/pull/43598) - fix(guardrails): enable explicit PANW MCP output scanning by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43109](https://github.com/BerriAI/litellm/pull/43109) - refactor(rust): orchestrate Messages route execution by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43719](https://github.com/BerriAI/litellm/pull/43719) - fix(streaming): keep the served service_tier on streamed chunks and spend rows by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​42870](https://github.com/BerriAI/litellm/pull/42870) - feat(bedrock): add openai gpt-6.1-sol global and base rows by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43758](https://github.com/BerriAI/litellm/pull/43758) - perf(router): fetch cooldown state and usage counters in one Redis round trip by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43320](https://github.com/BerriAI/litellm/pull/43320) - perf(proxy): hold one spend counter batch across admission and across post-call accounting by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43369](https://github.com/BerriAI/litellm/pull/43369) - perf(responses): run aresponses through the async wrapper so the cache is read once by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43769](https://github.com/BerriAI/litellm/pull/43769) - fix(router): bind Claude Code background sessions to their auto-router by [@​tin-berri](https://github.com/tin-berri) in [#​43767](https://github.com/BerriAI/litellm/pull/43767) - feat(bedrock): add openai.gpt-6.1-sol us geo cris and Mantle rows by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43763](https://github.com/BerriAI/litellm/pull/43763) - fix(proxy): recover session key owners from daily spend for usage attribution by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43642](https://github.com/BerriAI/litellm/pull/43642) - chore(cost-map): take azure context limits from models-sold-directly by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43759](https://github.com/BerriAI/litellm/pull/43759) - perf(proxy): one request-scoped Redis pipeline for auth, spend, rate-limit and routing reads by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43407](https://github.com/BerriAI/litellm/pull/43407) - fix(mcp): scope OpenAPI listings to the exact server prefix and drop upstream OAuth metadata when a server is saved by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43608](https://github.com/BerriAI/litellm/pull/43608) - perf(proxy): one post-call Redis pipeline per backend for spend, rate-limit, routing and response-cache writes by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43779](https://github.com/BerriAI/litellm/pull/43779) - fix(bedrock): set gpt-6.1-sol max output tokens to 131072 by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43782](https://github.com/BerriAI/litellm/pull/43782) - perf(proxy): refresh auth management objects through the request Redis pipeline by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43776](https://github.com/BerriAI/litellm/pull/43776) - feat(agents): add identity storage and validation contracts by [@​joshua-berri](https://github.com/joshua-berri) in [#​43720](https://github.com/BerriAI/litellm/pull/43720) - chore: bump litellm-enterprise 0.1.71 -> 0.1.72, litellm-proxy-extras 0.4.102 -> 0.4.103, litellm 1.104.0 -> 1.105.0 by [@​yuneng-berri](https://github.com/yuneng-berri) in [#​43789](https://github.com/BerriAI/litellm/pull/43789) - fix(auth): give UI/CLI session tokens their own AES-GCM context and header-safe shape by [@​yuneng-berri](https://github.com/yuneng-berri) in [#​43790](https://github.com/BerriAI/litellm/pull/43790) - chore(deps): bump pyjwt, moment and brace-expansion to clear osv-scan by [@​yuneng-berri](https://github.com/yuneng-berri) in [#​43792](https://github.com/BerriAI/litellm/pull/43792) - fix(ui): surface x-litellm-call-id in Logs search, table and drawer by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​42436](https://github.com/BerriAI/litellm/pull/42436) - fix(proxy): look up hashed key names with two spend log rows per key by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43656](https://github.com/BerriAI/litellm/pull/43656) - fix(cost-map): add deprecation_date to two together_ai nvidia rows by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43809](https://github.com/BerriAI/litellm/pull/43809) - test(ci): refresh retired OpenAI tool-call models by [@​yuneng-berri](https://github.com/yuneng-berri) in [#​43676](https://github.com/BerriAI/litellm/pull/43676) - fix(ui): keep MCP permissions visible after key, team and MCP server saves by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43810](https://github.com/BerriAI/litellm/pull/43810) - test(ci): repair MCP Responses and budget fixtures by [@​yuneng-berri](https://github.com/yuneng-berri) in [#​43788](https://github.com/BerriAI/litellm/pull/43788) - test(bedrock): accept regional aliases that inherit Converse routing by [@​yuneng-berri](https://github.com/yuneng-berri) in [#​43785](https://github.com/BerriAI/litellm/pull/43785) - fix(params): categorize internal param appropriately to prevent leaking into request by [@​shrey-berri](https://github.com/shrey-berri) in [#​43783](https://github.com/BerriAI/litellm/pull/43783) - perf(router): honour the cooldown read interval in the routing prefetch by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43815](https://github.com/BerriAI/litellm/pull/43815) - fix(router): carry per-request routing reads on context variables instead of public method kwargs by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43814](https://github.com/BerriAI/litellm/pull/43814) - fix(bedrock): add beta header for output config in message by [@​shrey-berri](https://github.com/shrey-berri) in [#​43778](https://github.com/BerriAI/litellm/pull/43778) - refactor: clean up fresh tech debt from 2026-09-29 by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43830](https://github.com/BerriAI/litellm/pull/43830) - test(router): settle the shared logging worker before recording shadow callbacks by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43847](https://github.com/BerriAI/litellm/pull/43847) - chore(model_prices): add Gemini Veo, Mistral and Azure Claude 4.5 deprecation dates by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43857](https://github.com/BerriAI/litellm/pull/43857) - fix(cost_calculator): bill ultrafast prompts above 272k at the ultrafast long-context rates by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43764](https://github.com/BerriAI/litellm/pull/43764) - refactor(rust): centralize Python bridge execution wrappers by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43871](https://github.com/BerriAI/litellm/pull/43871) - chore(cost-map): add openai gpt-image-2.5 batch prices from the pricing page by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43869](https://github.com/BerriAI/litellm/pull/43869) - chore(cost-map): add fireworks priority prices for ember-1, nemotron and glm 5.3 us rows by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43811](https://github.com/BerriAI/litellm/pull/43811) - fix(proxy): attribute completed batch cost rows to /batches in daily activity by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43870](https://github.com/BerriAI/litellm/pull/43870) - fix(router): strip encrypted reasoning the pinned deployment cannot decrypt by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43781](https://github.com/BerriAI/litellm/pull/43781) - fix(cost_calculator): stop copying optional_params into response hidden params by [@​yucheng-berri](https://github.com/yucheng-berri) in [#​43637](https://github.com/BerriAI/litellm/pull/43637) - feat(pricing): add vertex_ai gemini-3.8 flash tts rows by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43876](https://github.com/BerriAI/litellm/pull/43876) - fix(proxy): keep request-body credentials out of stored spend-log requests by [@​yucheng-berri](https://github.com/yucheng-berri) in [#​43635](https://github.com/BerriAI/litellm/pull/43635) - fix(ui): right-align money and count columns across tables by [@​ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#​37889](https://github.com/BerriAI/litellm/pull/37889) - feat(agents): enforce authoritative agent permissions by [@​joshua-berri](https://github.com/joshua-berri) in [#​43721](https://github.com/BerriAI/litellm/pull/43721) - fix(proxy): strip caller credentials from websocket passthrough by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43855](https://github.com/BerriAI/litellm/pull/43855) - fix(ui): render access group MCP and agent selections as wrapping chips by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​41228](https://github.com/BerriAI/litellm/pull/41228) - fix(responses): scan and mask top-level instructions with guardrails by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43629](https://github.com/BerriAI/litellm/pull/43629) - feat(traces): add Rust storage foundation by [@​yujonglee-berri](https://github.com/yujonglee-berri) in [#​43819](https://github.com/BerriAI/litellm/pull/43819) - feat(ui): agent traces tab on logs with timeline and otel setup guide by [@​ishaan-berri](https://github.com/ishaan-berri) in [#​43891](https://github.com/BerriAI/litellm/pull/43891) - feat(otel v2): excluded_services opt-out for datastore spans on tenant destinations by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43278](https://github.com/BerriAI/litellm/pull/43278) - fix(traces): correct ClickHouse rollup partitioning, dedupe keys, and retention changes by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43901](https://github.com/BerriAI/litellm/pull/43901) - fix(bedrock): keep applicable beta headers by [@​shrey-berri](https://github.com/shrey-berri) in [#​43829](https://github.com/BerriAI/litellm/pull/43829) - feat(agents): authenticate Entra identities and delegated requests by [@​joshua-berri](https://github.com/joshua-berri) in [#​43722](https://github.com/BerriAI/litellm/pull/43722) - fix(hosted_vllm): keep reasoning_content on replayed assistant messages by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43599](https://github.com/BerriAI/litellm/pull/43599) - fix(proxy): delete large teams without per-member transaction fan-out by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​42998](https://github.com/BerriAI/litellm/pull/42998) - feat(tracing): port OTLP ingestion to current trace foundation by [@​yujonglee-berri](https://github.com/yujonglee-berri) in [#​43915](https://github.com/BerriAI/litellm/pull/43915) - feat(proxy): add native ROI calculator for gateway spend vs merged PRs by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43669](https://github.com/BerriAI/litellm/pull/43669) - test(e2e): repair completion, SAIL, and spend-log fixtures by [@​yuneng-berri](https://github.com/yuneng-berri) in [#​43902](https://github.com/BerriAI/litellm/pull/43902) - test(s3_v2): pin async 5xx retry through the production AsyncHTTPHandler by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43080](https://github.com/BerriAI/litellm/pull/43080) - feat(ui): adopt the new LiteLLM logo and monogram by [@​yuneng-berri](https://github.com/yuneng-berri) in [#​43913](https://github.com/BerriAI/litellm/pull/43913) - fix(proxy): relay Azure passthrough body model groups through the router by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43896](https://github.com/BerriAI/litellm/pull/43896) - fix(proxy): register a UI-configured arize callback next to otel under OTel v2 by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43906](https://github.com/BerriAI/litellm/pull/43906) - fix(transcription): honor base_url alias for Groq Whisper and report it as the api base by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43917](https://github.com/BerriAI/litellm/pull/43917) - feat(tracing): store spend in ClickHouse automatically by [@​yujonglee-berri](https://github.com/yujonglee-berri) in [#​43928](https://github.com/BerriAI/litellm/pull/43928) - fix(packaging): keep wheel paths under Windows MAX_PATH for Store Python by [@​ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#​43903](https://github.com/BerriAI/litellm/pull/43903) - feat(agents): add identity registration and dashboard controls by [@​joshua-berri](https://github.com/joshua-berri) in [#​43723](https://github.com/BerriAI/litellm/pull/43723) - refactor(proxy): answer every team access check with TeamAccess.allows by [@​ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#​43364](https://github.com/BerriAI/litellm/pull/43364) - test(bedrock): restore the AWS env after a failed live call in the auth tests by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43921](https://github.com/BerriAI/litellm/pull/43921) - feat(lens): analyze agent activity with a separate worker by [@​moe-berri](https://github.com/moe-berri) in [#​43889](https://github.com/BerriAI/litellm/pull/43889) - fix(router): bill service tiers at catalog rates for custom-priced deployments by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43890](https://github.com/BerriAI/litellm/pull/43890) - test(ci): refresh qualified retired OpenAI fixtures by [@​yuneng-berri](https://github.com/yuneng-berri) in [#​43938](https://github.com/BerriAI/litellm/pull/43938) - fix(anthropic): forward the dangerous-tool-use beta to Azure AI Foundry by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43934](https://github.com/BerriAI/litellm/pull/43934) - test(proxy): scope user_api_key_auth overrides in proxy_server tests by [@​yuneng-berri](https://github.com/yuneng-berri) in [#​43952](https://github.com/BerriAI/litellm/pull/43952) - fix(wandb): set supports_vision true on GLM-5.3-Flash by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43951](https://github.com/BerriAI/litellm/pull/43951) - chore(cost-map): sync openrouter prices from the models API by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43950](https://github.com/BerriAI/litellm/pull/43950) - fix(grayswan): send request conversation and tool calls to post-call monitor by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43770](https://github.com/BerriAI/litellm/pull/43770) - fix(azure_storage): name Data Lake objects without base64 padding or slashes by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43914](https://github.com/BerriAI/litellm/pull/43914) - fix(guardrails): treat an unknown straiker api_version as unset instead of skipping the guardrail by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43956](https://github.com/BerriAI/litellm/pull/43956) - chore(deps): bump gitpython and tornado, extend diskcache osv ignore to Nov 1 by [@​yuneng-berri](https://github.com/yuneng-berri) in [#​43961](https://github.com/BerriAI/litellm/pull/43961) - fix(azure_storage): keep the DataLakeServiceClient alive until its TTL elapses by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43082](https://github.com/BerriAI/litellm/pull/43082) - feat(proxy): record in spend logs whether a request used a client-forwarded Anthropic OAuth token by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43063](https://github.com/BerriAI/litellm/pull/43063) - test(ci): repair stale tests and move retired OpenAI text-completion fixtures by [@​yuneng-berri](https://github.com/yuneng-berri) in [#​43958](https://github.com/BerriAI/litellm/pull/43958) - feat(e2e): record each e2e test's steps, starting with ProxyClient by [@​ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#​42393](https://github.com/BerriAI/litellm/pull/42393) - feat(providers): add Cortecs as an OpenAI-compatible provider by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43872](https://github.com/BerriAI/litellm/pull/43872) - feat(ui): filter tags by name and description on the Tag Management page by [@​galovics](https://github.com/galovics) in [#​42949](https://github.com/BerriAI/litellm/pull/42949) - fix(caching): write the response-cache SET to Redis at once instead of on the post-call batch by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43973](https://github.com/BerriAI/litellm/pull/43973) - test(e2e): typed per-test metadata for the e2e suite by [@​ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#​42044](https://github.com/BerriAI/litellm/pull/42044) - feat(guardrails): honor litellm_params.timeout in every HTTP guardrail by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43134](https://github.com/BerriAI/litellm/pull/43134) - chore(cost-map): add fireworks inkling priority prices from the prices api by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43949](https://github.com/BerriAI/litellm/pull/43949) - chore(cost-map): add deprecation date for anthropic claude-sonnet-4-5 by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43898](https://github.com/BerriAI/litellm/pull/43898) - fix(cost-map): raise baseten DeepSeek-V4.1-Flash max output to 262144 by [@​berriai-litellm-provider-info-sync](https://github.com/berriai-litellm-provider-info-sync)\[bot] in [#​43916](https://github.com/BerriAI/litellm/pull/43916) - fix(proxy): restore pre-config-wins handling of pass-through endpoints by [@​yuneng-berri](https://github.com/yuneng-berri) in [#​43962](https://github.com/BerriAI/litellm/pull/43962) - feat(lens): investigate sampled traces and retain batch results by [@​moe-berri](https://github.com/moe-berri) in [#​43942](https://github.com/BerriAI/litellm/pull/43942) - fix(guardrails): scan Responses API input in Azure Prompt Shield by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43786](https://github.com/BerriAI/litellm/pull/43786) - fix(guardrails): scan Responses API input in Azure Text Moderation by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43965](https://github.com/BerriAI/litellm/pull/43965) - refactor: clean up fresh tech debt from 2026-09-30 by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​43993](https://github.com/BerriAI/litellm/pull/43993) - test: inject the HIBP client and the MCP loop clock so two backend tests stop flaking by [@​devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#​44007](https://github.com/BerriAI/litellm/pull/44007) - fix(cost-map): reprice fireworks deepseek v4.1 flash to the 2026-10-01 pricing up…
TLDR
Problem this solves:
fallback_to_db_teamsignored once the JWT carried any team claimx-litellm-team-idnaming a DB membership team then 403'd against the JWT's teams onlyteam_id_jwt_field: appidorazptokens could never pick a second teamHow it solves it:
team_id_defaultstays out of the allowed set;team_allowed_routesand team models still applyIntentional product change: with
fallback_to_db_teams: true, the 403 for a header naming a team the caller is not a member of now reads "does not resolve to a team id or a unique team alias among your team memberships" instead of listing the JWT's allowed team ids. Same status, less disclosureUser Flow
Before: a developer whose Entra token resolves
appidto a team cannot bill a request to another team they belong tox-litellm-team-id: team-db-lit8656, a team they are a member ofx-litellm-team-id 'team-db-lit8656' does not resolve to a team id or a unique team alias in your JWT's allowed teams. Allowed team ids: ['d4e7111b-...']appidteam, not the one they asked forAfter: the same request is accepted and billed to the team named in the header
x-litellm-team-id: team-db-lit8656team-db-lit8656; the same call with no header still lands on theappidteam... among your team memberships.Linear ticket
Resolves LIT-8656
Pre-Submission checklist
Please complete all items before asking a LiteLLM maintainer to review your PR
uv run pytest tests/test_litellm/<your_test_file>.py -v. Leave the suites (make test-unit-*,make test-unit) to CI: it finishes in ~15 minutes where a laptop takes an hour or more@greptileaito re-request a review after pushing changes)Screenshots / Proof of Fix
Live proxy on localhost:4000 with Postgres,
PYTHONPATHpointed at this checkout, a real Entra client-credentials access token (tenant discovery JWKS viaJWT_PUBLIC_KEY_URL,JWT_AUDIENCEset to the app id) and real OpenAI calls togpt-5.5. The token'sappidclaim isd4e7111b-6000-4dec-ab57-f6896a44c340and itsoidis the user id. Seeded in the DB: teamd4e7111b-6000-4dec-ab57-f6896a44c340(the JWT team), teamteam-db-lit8656with the user as a member, and teamteam-other-lit8656without the user. The request body is the same file for every leg (sha25669691921...bff1e1)Before (5e6dc89)
A: no header (control)
run "A: no header (control)"HTTP/1.1 200 OKwith a chat completion;/spend/logsshows it under teamd4e7111b-6000-4dec-ab57-f6896a44c340B: header names a DB membership team
run "B" -H "x-litellm-team-id: team-db-lit8656"HTTP/1.1 403 Forbidden{"error":{"message":"x-litellm-team-id 'team-db-lit8656' does not resolve to a team id or a unique team alias in your JWT's allowed teams. Allowed team ids: ['d4e7111b-6000-4dec-ab57-f6896a44c340']","type":"auth_error","param":"None","code":"403"}}C: header names a team the user is not a member of
run "C" -H "x-litellm-team-id: team-other-lit8656"HTTP/1.1 403 Forbiddenwith the same "in your JWT's allowed teams. Allowed team ids: [...]" messageD: header names the JWT team
run "D" -H "x-litellm-team-id: d4e7111b-6000-4dec-ab57-f6896a44c340"HTTP/1.1 200 OK, billed tod4e7111b-6000-4dec-ab57-f6896a44c340After (373af8e, description text updated in b15d3d6)
A: no header (control)
run "A: no header (control)"HTTP/1.1 200 OK{"id":"chatcmpl-ES6aKbRYR715fBk8ygsmzvNj8zc3N",...};/spend/logs?request_id=chatcmpl-ES6aKbRYR715fBk8ygsmzvNj8zc3N->team_id d4e7111b-6000-4dec-ab57-f6896a44c340 success(JWT team still the default)B: header names a DB membership team
run "B" -H "x-litellm-team-id: team-db-lit8656"HTTP/1.1 200 OK{"id":"chatcmpl-ES6aLTqRgB65QGEfIrDh9UwPBkOCi",...}/spend/logs?request_id=chatcmpl-ES6aLTqRgB65QGEfIrDh9UwPBkOCi->team_id team-db-lit8656 successC: header names a team the user is not a member of
run "C" -H "x-litellm-team-id: team-other-lit8656"HTTP/1.1 403 Forbidden{"error":{"message":"x-litellm-team-id 'team-other-lit8656' does not resolve to a team id or a unique team alias among your team memberships.","type":"auth_error","param":"None","code":"403"}}D: header names the JWT team
run "D" -H "x-litellm-team-id: d4e7111b-6000-4dec-ab57-f6896a44c340"HTTP/1.1 200 OKwith a chat completion whose message content isOKE: header-selected DB team keeps its model list
curl -X POST localhost:4000/team/update -H "Authorization: Bearer $MASTER" -d '{"team_id":"team-db-lit8656","models":["gpt-4o-mini"]}'-> 200run "B" -H "x-litellm-team-id: team-db-lit8656"(body still asks forgpt-5.5)HTTP/1.1 403 Forbidden{"error":{"message":"The requested model 'gpt-5.5' is not available for this API key, or the model name is invalid. ...","type":"team_model_access_denied","param":"model","code":"403"}}Admin UI: Logs page
db-membership-team(red box,chatcmpl-ES6aLTqRgB65QGEfIrDh9UwPBkOCi), the no-header request still lands onentra-app-team, and the non-member header request is still a Failure. The topmost 20:13:55 Failure underdb-membership-teamis case E, the model list denialType
🐛 Bug Fix
Caveats
Scope with
sync_user_role_and_teams: true: sync already mirrors the JWT's team claims into the DB before the header is validated, so when the token carries claims the user's DB memberships are exactly the JWT teams and a header naming a team outside them is denied. That is the documented contract of sync (the IdP is the source of truth) and is unchanged here; with sync off, or with sync on and a claimless token, the header can select any DB membership team(if any)
Severe
fallback_to_db_teams: true, a JWT that carries a team claim may now be attributed to any DB team the caller is a member of viax-litellm-team-id. Operators who relied on the header being pinned to the JWT's teams should turn the flag offLow
/v1/chat/completions; header team resolution runs in the shared JWT auth step, so/v1/responsesand/v1/messagesgo through the same codeteam_allowed_routeson a header-selected team was not exercised live (config-level, needs a restart); covered bytest_auth_builder_header_alias_under_db_fallback_keeps_the_team_allowed_routes_gateand unchanged codetest_resolve_team_from_header_defers_to_db_membership_only_without_jwt_claims->..._accepts_db_teams_provisionally_under_fallback_even_with_jwt_claims) because its name described the old behavior; its assertions were kept and one case addedMutation check
Restoring the old
if fallback_to_db_teams and not allowed_team_ids:gate failstest_auth_builder_header_selects_db_membership_team_when_jwt_also_carries_a_team_claimand the renamed resolver test with the ticket's exact 403. Forcingprovisional_header_team = Nonefails the non-member,team_id_default, and three pre-existing membership andteam_allowed_routesdenial testsTaxonomy audit
Confirmed and accepted: C2 (non-member 403 text under the flag changes to the membership wording, same status, called out above). Checked not applicable: D2/Z7 (membership check runs on the resolved team id, denial names the sent value), D4/Z2 (every DB read failure on the provisional path maps to the membership denial, never an allow), Z1 (empty allowed set no longer changes the branch; provisional teams are always membership gated), P3 (RBAC-asserted team still cannot be overridden,
team_id is Noneguard kept), P4 (nonexistent and non-member teams return an identical 403), Z3 (team_allowed_routes, passthrough allowlist and team model list all still gate the header team), T1-T5/T17 (new tests fail on unfixed code, no weakened assertions, no global state), H1-H10 clean (no new comments, no em dashes,X | None, noAny)Final Attestation
Link to Devin session: https://app.devin.ai/sessions/8017fb00fe624daf9274d433e84ecfc7
Open in Devin Desktop: https://app.devin.ai/desktop/session/8017fb00fe624daf9274d433e84ecfc7?variant=devin
Requested by: @yassin-berriai